package com.guigusuqi.activiti.service.impl;

import com.guigusuqi.activiti.dto.BPMNFileDTO;
import com.guigusuqi.activiti.dto.TbFlowInsertDTO;
import com.guigusuqi.activiti.entity.TbFlow;
import com.guigusuqi.activiti.entity.TbSitemessage;
import com.guigusuqi.activiti.mapper.TbFlowMapper;
import com.guigusuqi.activiti.mapper.converter.FlowConvertMapper;
import com.guigusuqi.activiti.service.TbFlowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigusuqi.activiti.service.TbSitemessageService;
import com.guigusuqi.commonutils.exeception.BusinessException;
import com.guigusuqi.user.entity.LoginUser;
import com.guigusuqi.user.entity.SysUser;
import com.guigusuqi.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bytecode.Throw;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.io.*;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author suqi
 * @since 2023-06-15
 */
@Service
@Slf4j
public class TbFlowServiceImpl extends ServiceImpl<TbFlowMapper, TbFlow> implements TbFlowService
{
    @Resource
    private SysUserService userService;

    @Resource
    private TbSitemessageService siteMessageService;

    @Resource
    private RepositoryService repositoryService;

    @Resource
    private TbFlowMapper tbFlowMapper;

    /**
     * 任务创建事件
     * @param delegateTask
     */
    @Transactional
    public void createTaskEvent(DelegateTask delegateTask)
    {
        log.info("delegateTask=={}",delegateTask);
        //  负责人
        String assignee = delegateTask.getAssignee();
        //  获取当前登录用户

        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        SysUser user = userService.findOneUserByName(loginUser.getUser().getUserName());
        String userId = user.getUserId();
        //  任务id
        String taskId = delegateTask.getId();
        //  如果登录的用户不是这个任务的负责人，说明需要其他人进行审批，通知其他负责人
        if(!assignee.equals(userId))
        {
            int type = 1;
            TbSitemessage tbSitemessage = new TbSitemessage();
            tbSitemessage.setUserId(assignee);
            tbSitemessage.setTaskId(taskId);
            tbSitemessage.setType(type);
            tbSitemessage.setIsRead(1);
            siteMessageService.save(tbSitemessage);
        }
    }

    @Override
    public void createTbFlow(TbFlowInsertDTO tbFlowInsertDTO)
    {
        repositoryService.createDeployment().name(tbFlowInsertDTO.getFlowName())
                .addClasspathResource(tbFlowInsertDTO.getFilePath())
                .deploy();
        TbFlow tbFlow = FlowConvertMapper.FLOW_CONVERT_MAPPER.toInsertDTO(tbFlowInsertDTO);
        tbFlowMapper.insert(tbFlow);
    }

    @Override
    public void deleteAllFlow()
    {
        DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
        List<Deployment> list = deploymentQuery.list();
        for (Deployment deployment : list)
        {
            repositoryService.deleteDeployment(deployment.getId(),true);
        }
    }

    @Override
    public void getBPMNFile(BPMNFileDTO bpmnFileDTO) {
        String flowKey = bpmnFileDTO.getFlowKey();
        String fileURL = bpmnFileDTO.getFileURL();

        ProcessDefinition processDefinition = repositoryService.
                createProcessDefinitionQuery().
                processDefinitionKey(flowKey).
                singleResult();
        if (ObjectUtils.isEmpty(processDefinition)) {
            throw new BusinessException("没有该部署流程!");
        }
        String resourceName = processDefinition.getResourceName();
        InputStream bpmnInputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
        File bpmnFile = new File(fileURL);

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(bpmnFile);
            IOUtils.copy(bpmnInputStream, fileOutputStream);

            //  关闭流
            fileOutputStream.close();
            bpmnInputStream.close();

        } catch (FileNotFoundException e) {
            throw new BusinessException("该文件路径无法找到!");
        } catch (IOException e) {
            throw new BusinessException("文件传输有误!");
        }
    }

    @Override
    public void deleteProcessByDeploymentId(String flowKey)
    {
        ProcessDefinitionQuery processDefinitionQuery = repositoryService
                .createProcessDefinitionQuery();
        List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(flowKey).list();

        for (ProcessDefinition processDefinition : list)
        {
            repositoryService.deleteDeployment(processDefinition.getDeploymentId(), true);
        }
    }
}
